<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
    <link rel="stylesheet" href="style.css" type="text/css" />
    <style type="text/css">
        #controlToggle li {
            list-style: none;
        }
        p {
            width: 512px;
        }
        #options {
            position: relative;
            width: 512px;
        }
        #output {
            float: right;
        }
    </style>
    <script src="../lib/OpenLayers.js"></script>
    <script type="text/javascript">
        var map, measureControls;
        OpenLayers.Util.onImageLoadErrorColor = "transparent";
        function init(){
            map = new OpenLayers.Map('map');
            
            var wmsLayer = new OpenLayers.Layer.WMS( "OpenLayers WMS", 
                "http://labs.metacarta.com/wms/vmap0?", {layers: 'basic'}); 

            map.addLayers([wmsLayer]);
            map.addControl(new OpenLayers.Control.LayerSwitcher());
            map.addControl(new OpenLayers.Control.MousePosition());
            
            // style the sketch fancy
            sketchSymbolizers = {
                "Point": {
                    pointRadius: 4,
                    graphicName: "square",
                    fillColor: "white",
                    fillOpacity: 1,
                    strokeWidth: 1,
                    strokeOpacity: 1,
                    strokeColor: "#333333"
                },
                "Line": {
                    strokeWidth: 3,
                    strokeOpacity: 1,
                    strokeColor: "#666666",
                    strokeDashstyle: "dash"
                },
                "Polygon": {
                    strokeWidth: 2,
                    strokeOpacity: 1,
                    strokeColor: "#666666",
                    fillColor: "white",
                    fillOpacity: 0.3
                }
            };
            var style = new OpenLayers.Style();
            style.addRules([
                new OpenLayers.Rule({symbolizer: this.sketchSymbolizers})
            ]);
            var styleMap = new OpenLayers.StyleMap({"default": style});
            
            var options = {
                handlerOptions: {
                    style: "default", // this forces default render intent
                    layerOptions: {styleMap: styleMap},
                    persist: true
                }
            };
            measureControls = {
                line: new OpenLayers.Control.Measure(
                  OpenLayers.Handler.Path, options
                ),
                polygon: new OpenLayers.Control.Measure(
                    OpenLayers.Handler.Polygon, options
                )
            };
            
            var control;
            for(var key in measureControls) {
                control = measureControls[key];
                control.events.on({
                    "measure": handleMeasurements,
                    "measurepartial": handleMeasurements
                });
                map.addControl(control);
            }
            
            map.setCenter(new OpenLayers.LonLat(0, 0), 3);
            
            document.getElementById('noneToggle').checked = true;
        }

        function calcVincenty(geometry) {
            /**
             * Note: this function assumes geographic coordinates and
             *     will fail otherwise.  OpenLayers.Util.distVincenty takes
             *     two objects representing points with geographic coordinates
             *     and returns the geodesic distance between them (shortest
             *     distance between the two points on an ellipsoid) in *kilometers*.
             *
             * It is important to realize that the segments drawn on the map
             *     are *not* geodesics (or "great circle" segments).  This means
             *     that in general, the measure returned by this function
             *     will not represent the length of segments drawn on the map.
             */
            var dist = 0;
            for (var i = 1; i < geometry.components.length; i++) {
                var first = geometry.components[i-1];
                var second = geometry.components[i];
                dist += OpenLayers.Util.distVincenty(
                    {lon: first.x, lat: first.y},
                    {lon: second.x, lat: second.y}
                );
            }
            return dist;
        }    
        
        function handleMeasurements(event) {
            var geometry = event.geometry;
            var units = event.units;
            var order = event.order;
            var measure = event.measure;
            var element = document.getElementById('output');
            var out = "";
            if(order == 1) {
                out += "measure: " + measure.toFixed(3) + " " + units;
                if (map.getProjection() == "EPSG:4326") {
                    out += "<br /> Great Circle Distance: " + 
                        calcVincenty(geometry).toFixed(3) + " km *"; 
                }        
            } else {
                out += "measure: " + measure.toFixed(3) + " " + units + "<sup>2</" + "sup>";
            }
            element.innerHTML = out;
        }

        function toggleControl(element) {
            for(key in measureControls) {
                var control = measureControls[key];
                if(element.value == key && element.checked) {
                    control.activate();
                } else {
                    control.deactivate();
                }
            }
        }
    </script>
  </head>
  <body onload="init()">
    <h1 id="title">OpenLayers Measure Example</h1>
    <p id="shortdesc">
        Demonstrates the measure control to measure distances and areas.
    </p>
    <div id="map" class="smallmap"></div>
    <div id="options">
        <div id="output">
        </div>
        <ul id="controlToggle">
            <li>
                <input type="radio" name="type" value="none" id="noneToggle"
                       onclick="toggleControl(this);" checked="checked" />
                <label for="noneToggle">navigate</label>
            </li>
            <li>
                <input type="radio" name="type" value="line" id="lineToggle" onclick="toggleControl(this);" />
                <label for="lineToggle">measure distance</label>
            </li>
            <li>
                <input type="radio" name="type" value="polygon" id="polygonToggle" onclick="toggleControl(this);" />
                <label for="polygonToggle">measure area</label>
            </li>
        </ul>
        <p>* Note that the geometries drawn are planar geometries and the
        metrics returned by the measure control are planar measures.  The
        "great circle" distance does not necessarily represent the length
        of the segments drawn on the map.  Instead, it is a geodesic metric that
        represents the cumulative shortest path between all vertices in the
        geometry were they projected onto a sphere.</p>
    </div>
  </body>
</html>
